package com.tdk.mybatisplus.demo.common.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.google.common.net.HttpHeaders;

import com.tdk.mybatisplus.demo.common.entity.ICodeNameMapping;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.jackson.JsonObjectSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static com.tdk.mybatisplus.demo.common.entity.Constants.DATE_TIME_PATTERN;

/**
 * <p>
 * 创建bean交给spring ioc
 * </p>
 *
 * @author: taodingkai
 * @modified:
 * @since: 2022/08/08 14:16
 */
@Configuration
public class BeanInitConfig {

    /**
     * <p>
     * 跨域设置
     * </p>
     *
     * @return org.springframework.web.filter.CorsFilter
     * @author: taodingkai
     * @since: 2022/08/08 17:09
     */
    @Bean
    public CorsFilter corsFilter() {
        //1. 添加 CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        //放行哪些原始域
        config.addAllowedOrigin("*");
        //是否发送 Cookie
        config.setAllowCredentials(true);
        //放行哪些请求方式
        config.addAllowedMethod("*");
        //放行哪些原始请求头部信息
        config.addAllowedHeader("*");
        //暴露哪些头部信息
        config.addExposedHeader(HttpHeaders.ACCEPT);
        //2. 添加映射路径
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**", config);
        //3. 返回新的CorsFilter
        return new CorsFilter(corsConfigurationSource);
    }

    /**
     * <p>
     * RestTemplate
     * </p>
     *
     * @return org.springframework.web.client.RestTemplate
     * @author: taodingkai
     * @since: 2022/08/08 17:08
     */
    @Bean
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(15000);
        factory.setReadTimeout(15000);
        return new RestTemplate(factory);
    }

    /**
     * <p>
     * HttpHeaders
     * </p>
     *
     * @return org.springframework.http.HttpHeaders
     */
    @Bean
    public org.springframework.http.HttpHeaders headers() {
        org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return headers;
    }


    /**
     * <p>
     * localDateTime 序列化器
     * </p>
     *
     * @return com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
     * @author: taodingkai
     * @since: 2022/8/11 17:20
     */
    @Bean
    public LocalDateTimeSerializer localDateTimeSerializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN));
    }

    /**
     * <p>
     * localDateTime 反序列化器
     * </p>
     *
     * @return com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer
     * @author: taodingkai
     * @since: 2022/8/11 17:20
     */
    @Bean
    public LocalDateTimeDeserializer localDateTimeDeserializer() {
        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN));
    }


    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            builder.serializerByType(LocalDateTime.class, localDateTimeSerializer());
            builder.deserializerByType(LocalDateTime.class, localDateTimeDeserializer());
            builder.simpleDateFormat(DATE_TIME_PATTERN);
            builder.serializerByType(ICodeNameMapping.class, new JsonObjectSerializer<ICodeNameMapping>() {
                        @Override
                        protected void serializeObject(ICodeNameMapping value, JsonGenerator generator, SerializerProvider provider) throws IOException {
                            //这里是给枚举序列化的
                            Boolean flag = Boolean.TRUE;
                            try {
                                generator.writeStartObject();
                            } catch (Exception e) {
                                flag = Boolean.FALSE;
                            }
                            generator.writeObjectField("code", value.getCode());
                            generator.writeObjectField("name", value.getName());
                            if (flag) {
                                generator.writeEndObject();
                            }
                        }
                    }
            );
        };
    }
    
    @Bean
    ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
    
}
